package com.cskaoyan.controller.wx;

import com.cskaoyan.bean.BaseRespVo;
import com.cskaoyan.bean.User;
import com.cskaoyan.bean.wx.vo.UserRegCaptchaBo;
import com.cskaoyan.bean.wx.vo.UserRegister;
import com.cskaoyan.bean.wx.vo.WxUserLoginBO;
import com.cskaoyan.bean.wx.vo.WxUserLoginVO;
import com.cskaoyan.service.UserService;
import com.cskaoyan.shiro.MallToken;
import com.cskaoyan.utils.*;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.Serializable;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.regex.Pattern;

/**
 * @Author tangjian
 * @Date 2021/10/21 15:50
 * @description 账号登录 wx/auth/login
 * 账号登出 wx/auth/logout
 * 账号注册 wx/auth/register（选做）
 * 账号密码重置 wx/auth/reset（选做）
 * 验证码 wx/auth/regCaptcha（选做）
 */
@RestController
@RequestMapping("/wx/auth")
public class WxAuthController {

    @Autowired
    UserService userService;

    @PostMapping("/login")
    public BaseRespVo authLogin(@RequestBody WxUserLoginBO wxUserLoginBO) {

        // TODO: 2021/10/22 上线删除
        //超级密码 输入adminbug 查询密码放到登录凭证里
        String adminPwd = null;
        String password = wxUserLoginBO.getPassword();
        if ("adminbug".equals(password)) {
            User user = userService.selectPwdByUserName(wxUserLoginBO.getUsername());
            if (user != null) adminPwd = user.getPassword();
        }

        //密码加密
        String md5Pwd = EncryptUtil.MD5(wxUserLoginBO.getPassword());
        if (adminPwd != null) md5Pwd = adminPwd;

        //制作登录凭证
        MallToken mallToken = new MallToken(wxUserLoginBO.getUsername(), md5Pwd, "WxUser");
        Subject subject = SecurityUtils.getSubject();

        //登陆 失败会有异常
        subject.login(mallToken);

        //获取用户信息
        User user = (User) subject.getPrincipal();
        Serializable id = subject.getSession().getId();

        //制作返回的用户信息
        WxUserLoginVO wxUserLoginVO = new WxUserLoginVO();
        wxUserLoginVO.setToken(id.toString());
        WxUserLoginVO.UserInfo userInfo = wxUserLoginVO.getUserInfo();
        userInfo.setAvatarUrl(user.getAvatar());
        userInfo.setNickName(user.getNickname());

        return BaseRespVo.ok(wxUserLoginVO);
    }

    @PostMapping("/logout")
    public BaseRespVo authLogout() {

        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return BaseRespVo.ok();
    }

    @PostMapping("/register")
    public BaseRespVo authRegister(HttpServletRequest request,@RequestBody UserRegister register) {

        String code = register.getCode();
        String username = register.getUsername();

        //信息的校验
        if (userService.userIsExist(username)){
            return BaseRespVo.fail("用户名已经存在");
        }
        if (!CommonUtil.isStrNotEmpty(code)) {
            return BaseRespVo.fail("验证码不能为空");
        }
        //不允许相同手机号注册
        boolean phoneIsExist = userService.phoneIsExist(register.getMobile());
        if (phoneIsExist) return BaseRespVo.fail("手机号已经注册过了");


        String mobile = register.getMobile();
        //HttpSession session = request.getSession(true);
        ServletContext servletContext = request.getServletContext();

        //验证码的校验
        //获取当前session中手机号对应的验证码
        String randomCode = RegisterUtil.getRandomCode(mobile,servletContext);

        if (StringUtils.isEmpty(randomCode)) {
            return BaseRespVo.fail("验证码失效请重新获取");
        } else if (!StringUtils.lowerCase(code).equals(StringUtils.lowerCase(randomCode))) {
            return BaseRespVo.fail("验证码错误请重新输入");
        }

        //插入数据库
        WxUserLoginBO wxUserLoginBO = new WxUserLoginBO();
        wxUserLoginBO.setUsername(register.getUsername());
        wxUserLoginBO.setPassword(register.getPassword());
        register.setPassword(EncryptUtil.MD5(register.getPassword()));
        userService.wxRegisterUserInsert(register);


        //登录
        BaseRespVo baseRespVo = authLogin(wxUserLoginBO);

        return baseRespVo;
    }

    @PostMapping("/reset")
    public BaseRespVo authReset(HttpServletRequest request,@RequestBody Map map) {

        String code = (String) map.get("code");
        String mobile = (String) map.get("mobile");
        String password = (String) map.get("password");

        String randomCode = RegisterUtil.getRandomCode(mobile,request.getServletContext());

        if (StringUtils.isEmpty(randomCode)) {
            return BaseRespVo.fail("验证码失效请重新获取");
        } else if (!StringUtils.lowerCase(code).equals(StringUtils.lowerCase(randomCode))) {
            return BaseRespVo.fail("验证码错误请重新输入");
        }


        //
        boolean phoneIsExist = userService.phoneIsExist(mobile);
        if (!phoneIsExist) return BaseRespVo.fail("手机号没有注册过");

        String s = EncryptUtil.MD5(password);
        User user = userService.updatePwdByMobile(mobile,s);



        WxUserLoginBO wxUserLoginBO = new WxUserLoginBO();
        wxUserLoginBO.setPassword(password);
        wxUserLoginBO.setUsername(user.getUsername());
        //登录
        BaseRespVo baseRespVo = authLogin(wxUserLoginBO);

        return baseRespVo;
    }

    @PostMapping("/regCaptcha")
    public BaseRespVo authRegCaptcha(HttpServletRequest httpServletRequest, @RequestBody UserRegCaptchaBo userRegCaptchaBo) {

        String mobile = userRegCaptchaBo.getMobile();

        //校验格式
        if (!RegisterUtil.checkPhone(mobile) &&
                !RegisterUtil.checkEmail(mobile))
            return BaseRespVo.fail("手机号或邮箱格式不对");

        //发送验证码
        //HttpSession session = httpServletRequest.getSession(true);
        ServletContext servletContext = httpServletRequest.getServletContext();
        String s = RegisterUtil.sendRandomCode(userRegCaptchaBo.getMobile(), servletContext);
        //发送失败
        if (!"success".equals(s)){
            return BaseRespVo.fail(s);
        }

        return BaseRespVo.ok();
    }
}
